package data

/*******************************************************************************
Copyright:cloud
Author:cloudapex@126.com
Version:1.0
Date:2020-06-12
Description: 数据库控制器
*******************************************************************************/
import (
	"fmt"
	"permissions/conf"

	"gitee.com/cloudapex/ulern/cto"
	"gitee.com/cloudapex/ulern/util"
	_ "github.com/go-sql-driver/mysql"
	"xorm.io/core"
	"xorm.io/xorm"
	"xorm.io/xorm/log"
)

var MDB *mdb

func init() { MDB = cto.Install("MC_MySql", &mdb{}).(*mdb) }

type mdb struct {
	cto.ControlBase

	hands []*xorm.Engine
	syncs [][]interface{}
}

func (this *mdb) HandleInit() {
	this.ControlBase.HandleInit()
	this.initMDBConfig()
}
func (this *mdb) HandleTerm() {
	for _, x := range this.hands {
		x.Close()
	}
	this.ControlBase.HandleTerm()
}

// -------- public
func (this *mdb) Use(nIndex int) *xorm.Engine {
	if nIndex < len(this.hands) {
		return this.hands[nIndex]
	}
	return nil
}
func (this *mdb) Sync(nIndex int, tbl ...interface{}) {
	if nIndex >= len(this.syncs) {
		this.syncs = append(this.syncs, make([][]interface{}, nIndex-len(this.syncs)+1)...)
	}
	this.syncs[nIndex] = append(this.syncs[nIndex], tbl...)
}

// -------- internal
func (this *mdb) initMDBConfig() {
	for n, cof := range conf.DB.MDBs() {
		source := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
			cof.DBUser, cof.DBPass, cof.DBHome, cof.DBPort, cof.DBName)
		x, err := xorm.NewEngine("mysql", source)
		if err != nil {
			this.Fatalv(err)
		}

		x.SetLogger(&XormLogger{})
		x.SetLogLevel(log.LogLevel(util.Max(int(util.Log.GetLevel()-1), 0)))
		if err := x.Ping(); err != nil {
			this.Fatalv(err)
		}

		x.SetTableMapper(core.SnakeMapper{})
		x.SetColumnMapper(core.SnakeMapper{})
		x.SetMaxIdleConns(DEF_DBCONN_IDLE_MAX)
		x.SetMaxOpenConns(DEF_DBCONN_OPEN_MAX)
		//x.SetTableMapper(core.NewPrefixMapper(core.SnakeMapper{}, DEF_TABLE_PREFIX))

		x.ShowSQL(conf.DB.ShowSQL())

		if n < len(this.syncs) {
			for _, it := range this.syncs[n] {
				if err = x.Sync2(it); err != nil {
					this.Fatal("Sync tbl[%q] err:%v", x.TableName(it), err)
				}
			}
		}
		this.hands = append(this.hands, x)
	}
}
